#-*- coding: utf-8 -*-
import pygame
import colors
import copy
import random

class Peg:
    def __init__(self, type, x, y):
        self.type = type
        self.x = x
        self.y = y

    def getRect(self):
        return pygame.Rect(self.x - 15, self.y - 15, 30, 30)

    def draw(self, surface):
        pygame.draw.circle(surface, colors.colors[self.type], (self.x, self.y), 15, 0)

    def copyTo(self, x, y):
        cp = copy.copy(self)
        cp.x = x
        cp.y = y
        return cp

    def __cmp__(self, other):
        if self is None or other is None:
            return True
        else:
            return not (self.type == other.type)
class SolutionPeg(Peg):
    def __init__(self, type, x, y):
        Peg.__init__(self, type, x, y)

    def draw(self, surface):
        if self.type == True:
            pygame.draw.circle(surface, (255, 0, 0), (self.x, self.y), 5)
        else:
            pygame.draw.circle(surface, (255, 255, 255), (self.x, self.y), 5)

class EmptySolutionPeg(SolutionPeg):
    def __init__(self, x, y):
        SolutionPeg.__init__(self, None, x, y)

    def draw(self, surface):
        pygame.draw.circle(surface, (0, 0, 0), (self.x, self.y), 5)

class EmptyPeg(Peg):
    def __init__(self, x = 0, y = 0):
        Peg.__init__(self, -1, x, y)

    def draw(self, surface):
        pygame.draw.circle(surface, (0, 0, 0), (self.x, self.y), 15, 0)

class Row:
    def __init__(self, x, y, rand = False):
        self.codePegs = [EmptyPeg(20, 20),
                         EmptyPeg(60, 20),
                         EmptyPeg(100, 20),
                         EmptyPeg(140, 20)]
        self.keyPegs = [EmptySolutionPeg(170, 10),
                        EmptySolutionPeg(190, 10),
                        EmptySolutionPeg(170, 30),
                        EmptySolutionPeg(190, 30)
                        ]
        self.x = x
        self.y = y

        if rand == True:
            self.codePegs = [Peg(random.randint(0,len(colors.colors.keys()) - 1), 0, 0),
                             Peg(random.randint(0,len(colors.colors.keys()) - 1), 0, 0),
                             Peg(random.randint(0,len(colors.colors.keys()) - 1), 0, 0),
                             Peg(random.randint(0,len(colors.colors.keys()) - 1), 0, 0)]

    def getRect(self):
        return pygame.Rect(self.x, self.y, 200, 40)

    def moveDown(self, dist):
        self.y += dist

        for peg in self.codePegs:
            peg.y += dist

        for peg in self.keyPegs:
            peg.y += dist

    def onclick(self, (x, y), peg):
        for i in range(len(self.codePegs)):
            if self.codePegs[i].getRect().collidepoint((x,y)):
                (cx, cy) = (self.codePegs[i].x, self.codePegs[i].y)
                self.codePegs[i] = peg.copyTo(cx, cy)

    def draw(self, surface):
        for peg in self.codePegs:
            peg.draw(surface)

        for peg in self.keyPegs:
            peg.draw(surface)

    def check(self, other):
        # make pegs for comparison
        pegs = zip(self.codePegs, other.codePegs)

        # calculate pegs
        redPegsCount = len([elem for elem in pegs if elem[0] == elem[1]])

        # get the rest of the pegs
        whitePegsCount = 0
        selfPegs = [elem[0] for elem in pegs if elem[0] != elem[1]]
        otherPegs = [elem[1] for elem in pegs if elem[0] != elem[1]]

        for peg in selfPegs:
            if peg in otherPegs:
                whitePegsCount += 1
                otherPegs.remove(peg)


        # return the KeyPegsRow
        print redPegsCount, whitePegsCount

        # draw the key pegs
        for i in range(redPegsCount):
            x = self.keyPegs[i].x
            y = self.keyPegs[i].y
            self.keyPegs[i] = SolutionPeg(True, x, y)

        for i in range(redPegsCount, redPegsCount + whitePegsCount):
            x = self.keyPegs[i].x
            y = self.keyPegs[i].y
            self.keyPegs[i] = SolutionPeg(False, x, y)

        if redPegsCount == 4:
            return True
        else:
            return False


class Picker:
    pegs = []
    current = None

    def __init__(self):
        self.current = EmptyPeg()

        # first column
        self.pegs.append(Peg(colors.RED, 20, 20))
        self.pegs.append(Peg(colors.LIGHTGREEN, 20, 60))
        self.pegs.append(Peg(colors.BLUE, 20, 100))
        self.pegs.append(Peg(colors.YELLOW, 20, 140))

        # second column
        self.pegs.append(Peg(colors.PINK, 60, 20))
        self.pegs.append(Peg(colors.ORANGE, 60, 60))
        self.pegs.append(Peg(colors.GREEN, 60, 100))
        self.pegs.append(Peg(colors.BROWN, 60, 140))


    def draw(self, surface):
        # prepare surface
        surface.fill((0, 0, 0))
        # mark selected

        if self.current != EmptyPeg():
            pygame.draw.circle(surface, (255, 255, 255), (self.current.x, self.current.y), 20)

        for peg in self.pegs:
            peg.draw(surface)

    def onclick(self, (x, y), offset = (0, 0)):
        pos = (x - offset[0], y - offset[1])
        for p in self.pegs:
            if p.getRect().collidepoint(pos):
                if self.current == p:
                    self.current = EmptyPeg()
                else:
                    self.current = p
                break

class Board:
    def __init__(self):
        self.rows = []
        self.secretRow = Row(0,0,True)

        self.rows.append(Row(0, 0))

    def draw(self, surface):
        for row in self.rows:
            row.draw(surface)

    def onclick(self, (x, y), offset = (0,0), peg = EmptyPeg()):
        pos = (x - offset[0], y - offset[1])
        if self.rows[-1].getRect().collidepoint(pos):
            self.rows[-1].onclick(pos, peg)

    def check(self):
        if len([peg for peg in self.rows[-1].codePegs if peg.type >= 0]) == 4:
            # check if the pegs are all correct
            result = self.rows[-1].check(self.secretRow)

            if not result:
                if len(self.rows) < 3:
                    for row in self.rows:
                        row.moveDown(40)

                    self.rows.append(Row(0,0))
                else:
                    result = True

            return result




